﻿using System;
using System.Collections.Generic;
using System.Text;

namespace System.Data.SugarClient.Soap.V1
{
	internal class V1GetEntryAction : V1ModuleAction
	{

		#region Constructors

		internal V1GetEntryAction(
			SugarSoapV1.sugarsoap service,
			string session,
			string module,
			string id,
			string[] fields)
			: base(service, session, module) 
		{
			this._id = id;
			this._fields = fields;
			this.CheckFieldAvailablility();
		}

		#endregion

		#region Fields

		private readonly string _id;
		private readonly string[] _fields;

		#endregion

		#region Properties

		public string Id
		{
			get { return _id; }
		} 

		public string[] Fields
		{
			get { return _fields; }
		}

		#endregion

		protected override V1ActionResult ExecuteInner()
		{
			var result =
				this.SoapService.get_entry(
					this.Session,
					this.Module,
					this.Id,
					this.Fields);

			return new V1GetEntryActionResult(this, result);
		}

		internal protected string[] CheckFieldAvailablility()
		{
			V1GetModuleFieldsAction action = new V1GetModuleFieldsAction(this.SoapService, this.Session, this.Module);
			V1GetModuleFieldsActionResult result = action.Execute() as V1GetModuleFieldsActionResult;
			if (!result.Success) throw new SugarException("Can not get field list");
			List<string> target = new List<string>(this.Fields);
			foreach (SugarVarDef vardef in result.VarDefs)
			{
				target.Contains(vardef.Name);
				target.Remove(vardef.Name);
				if (target.Count == 0) return new string[]{};
			}

			if (0 < target.Count) return target.ToArray();
			else return new string[] { };
		}
	}

	internal class V1GetEntryActionResult : V1ModuleActionResult, IGetEntryActionResult
	{

		internal V1GetEntryActionResult(
			V1GetEntryAction action,
			SugarSoapV1.get_entry_result result)
			: base(action)
		{
			this._result = result;
		}

		private readonly SugarSoapV1.get_entry_result _result;

		internal SugarSoapV1.get_entry_result RawResult
		{
			get { return _result; }
		}

		public virtual bool Success
		{
			get
			{
				if (RawResult.error == null) return true;
				else if (RawResult.error.number == null) return true;
				else if ("0".Equals(RawResult.error.number)) return true;
				else return false;
			}
		}

		public V1GetEntryAction Action
		{
			get { return base.Action as V1GetEntryAction; }
		}

		#region IGetEntryListActionResult メンバ

		public int FieldCount
		{
			get { return this.Action.Fields.Length; }
		}

		public object this[int col]
		{
			get { return GetValueOf(0, col); }
		}

		#endregion

		#region Methods

		#region IGetEntryListActionResult メンバ

		public  string GetFieldNameAt(int index)
		{
			return this.Action.Fields[index];
		}

		public object GetValueOf(int index, int ordinal)
		{
			var entry = this.RawResult.entry_list[index];
			return
				Array.Find<SugarSoapV1.name_value>(
					entry.name_value_list,
					(v) => v.name.Equals(GetFieldNameAt(ordinal))).value;
		}

		public SugarVarDef GetVarDefAt(int index)
		{
			return
				SugarVarDef.Create(
					Array.Find<SugarSoapV1.field>(
						this.RawResult.field_list,
						(f) => f.name.Equals(this.Action.Fields[index])));
		}

		public int IndexOf(string field)
		{
			return Array.IndexOf(this.Action.Fields, field);
		}

		#endregion

		#endregion

		
	}

}
